package si.banst.tecajnice.ejb;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import si.banst.tecajnice.ejb.napake.NapacniArgumenti;
import si.banst.tecajnice.ejb.napake.NapakaPriPosodobitvi;
import si.banst.tecajnice.ejb.napake.NapakaPriPovprasevanju;
import si.banst.tecajnice.ejb.napake.NapakaPriZapisu;
import si.banst.tecajnice.ejb.prestrezniki.SledenjeZahtevam;
import si.banst.tecajnice.entitete.Valuta;

/**
 * Session Bean implementation class ValuteBean
 */
@Stateless
@Interceptors(SledenjeZahtevam.class)
@RolesAllowed({ "OdgovorniReferent", "ReferentZaPreracun", "Referent", "PoslovniPartnerji" })
public class ValuteBean implements ValuteBeanLocal, ValuteBeanRemote {

	private static final Logger logger = Logger.getLogger(ValuteBean.class
			.getName());

	@PersistenceContext(unitName = "tecajnice-jpa")
	private EntityManager em;

	/**
	 * Default constructor.
	 */
	public ValuteBean() {
		super();
	}

	@PostConstruct
	public void init() {
		logger.fine("Preverjam povezavos s persistečno enoto");
		if (em == null) {
			logger.severe("Povezava z persistencno enoto tecajnice-jpa ni vzpostavljena.");
			throw new EJBException(
					"Povezava z persistencno enoto tecajnice-jpa ni vzpostavljena.");
		}
	}

	@Override
	public List<Valuta> vrniVseValute() throws NapakaPriPovprasevanju {
		try {
			@SuppressWarnings("unchecked")
			List<Valuta> valute = em.createNamedQuery("vrniVseValute")
					.getResultList();
			logger.fine("Povpraševanje uspešno izvedeno.");
			return valute;
		} catch (Exception e) {
			logger.severe("Napaka pri povprasevanju." + e.getMessage());
			throw new NapakaPriPovprasevanju(e);
		}
	}

	@Override
	public Valuta vrniValuto(int sifraValute) throws NapacniArgumenti,
			NapakaPriPovprasevanju {
		try {
			Valuta valuta = em.find(Valuta.class, sifraValute);
			logger.fine("Povpraševanje uspešno izvedeno.");
			return valuta;
		} catch (Exception e) {
			logger.severe("Napaka pri povprasevanju." + e.getMessage());
			throw new NapakaPriPovprasevanju(e);
		}
	}

	@Override
	public Valuta vrniValutoZOznako(String oznakaValute)
			throws NapacniArgumenti, NapakaPriPovprasevanju {
		try {
			Query povprasevanje = em.createNamedQuery("vrniValutoZOznako");
			povprasevanje.setParameter("oznakaValute", oznakaValute);
			Valuta valuta = (Valuta) povprasevanje.getSingleResult();
			logger.fine("Povpraševanje uspešno izvedeno.");
			return valuta;
		} catch (Exception e) {
			logger.severe("Napaka pri povprasevanju." + e.getMessage());
			throw new NapakaPriPovprasevanju(e);
		}
	}

	@Override
	@RolesAllowed({ "OdgovorniReferent", "ReferentZaPreracun" })
	public void zapisiValuto(Valuta valuta) throws NapakaPriZapisu {
		try {
			em.persist(valuta);
			logger.fine("Zapis uspešno vstavljen.");
		} catch (Exception e) {
			logger.severe("Napaka pri zapisovanju." + e.getMessage());
			throw new NapakaPriZapisu(e);
		}

	}

	@Override
	@RolesAllowed({ "OdgovorniReferent", "ReferentZaPreracun" })
	public void posodobiValuto(Valuta valuta) throws NapakaPriPosodobitvi {
		try {
			em.merge(valuta);
			logger.fine("Zapis uspešno posodobljen.");
		} catch (Exception e) {
			logger.severe("Napaka pri posodobitvi." + e.getMessage());
			throw new NapakaPriPosodobitvi(e);
		}

	}

	@Override
	public List<Valuta> vrniValute(List<Integer> sifraValute)
			throws NapacniArgumenti, NapakaPriPovprasevanju {
		List<Valuta> valute = new ArrayList<Valuta>();
		for (Integer sifra : sifraValute) {
			Valuta valuta = vrniValuto(sifra.intValue());
			if (valuta != null)
				valute.add(valuta);
		}
		return valute;
	}

	@Override
	public List<Valuta> vrniValuteZOznako(List<String> oznakeValut)
			throws NapacniArgumenti, NapakaPriPovprasevanju {
		List<Valuta> valute = new ArrayList<Valuta>();
		for (String oznaka : oznakeValut) {
			Valuta valuta = vrniValutoZOznako(oznaka);
			if (valuta != null)
				valute.add(valuta);
		}
		return valute;
	}

	@Override
	@RolesAllowed({ "OdgovorniReferent", "ReferentZaPreracun" })
	public void posodobiValute(List<Valuta> valute) throws NapakaPriPosodobitvi {
		for (Valuta valuta : valute) {
			posodobiValuto(valuta);
		}
	}

}
